<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模拟聊天室并发造成的性能问题，阐述队列与时序重要性</title>
    <style>
        body{
            color:rgb(41, 41, 41);
            font-size:16px;
        }
        .message{
            width:100%;
            height:300px;
            border:1px solid #cecece;
            padding:15px;
            box-sizing: border-box;
            overflow: auto;
        }
        .block{
            margin-bottom:15px;
        }
        .block,.line{
            width:100%;
            float:left;
        }
        .lineBg{
            background:rgb(231, 231, 231);
            border-radius: 8px;
            padding:6px 10px;
            box-sizing: border-box;
            margin-top:5px;
            float:left;
        }
        .rele{
            width:100%;
            height:100%;
            overflow: visible;
            position: relative;
        }
        .msg_top{
            width: 0;
            height: 0;
            border-left: 1px solid transparent;
            border-right: 12px solid transparent;
            border-bottom: 10px solid rgb(231, 231, 231);
            position: absolute;
            top:-2px;
            left:8px;
        }
        .send{
            margin-top:15px;
        }
        .text1{
            width:100%;
            height:100px;
            resize: none;
            padding:10px;
            box-sizing: border-box;
            border-color: rgb(45, 155, 228);
            outline: none;
            font-size: 16px;
        }
        .submit{
            float:right;
            background-color: rgb(45, 155, 228);
            color:#ffffff;
            padding:5px 10px;
            border-radius: 3px;
            cursor: pointer;
            margin-left:15px;
        }
        .submit:active{
            background-color: rgb(117, 189, 238);
        }
        .submit_gray{
            background-color: #cecece;
            color:rgb(68, 68, 68);
        }
        .left{
            float:left;
            width:auto;
            line-height:30px;
        }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>

    <div class="content" id="content">
        <div class="message" id="message">

            <div class="block" v-for="(val, index) in list" :key="index">
                <div class="line">用户 {{val.user}} 说：</div>
                <div class="line">
                    <div class="rele">
                        <div class="msg_top"></div>
                        <div class="lineBg">{{val.text}}</div>
                    </div>
                </div>
            </div>

        </div>
        <div class="send">
            <textarea class="text1" v-model="text"></textarea>
            <div class="submit" @click="submit">发送</div>
            <div class="submit" @click="demo">模拟多个人同时说话，队列形式</div>
            <div class="submit submit_gray" @click="demo('all')">模拟多个人同时说话，一次全部显示出来</div>
            <div class="line left">总耗时：{{timeConsuming}} 毫秒</div>
        </div>
    </div>

    <script>

        var geolocation = new Vue({
            el: '#content',
            data: {
                list:[],
                text:'',
                index:1,
                tempList:[],    //消息队列
                timer:null, //定时器对象
                flag:false, //启动轮询队列
                person:10000,  //多少个人同时说话
                timeConsuming:0,    //执行耗时
            },
            mounted() {
            },
            methods: {
                //发送消息
                submit(){
                    //加入队列
                    this.tempList.push({
                        user:this.index,
                        text:this.text,
                    });
                    this.index++;
                    this.text = '';
                    //启动定时器
                    this.openTimer();
                },
                //启动定时器
                openTimer(){
                    if(!this.flag){                        
                        //启动定时器，轮询队列
                        this.setTimer();
                        this.flag = true;
                    }
                },
                //定时器，轮询队列
                setTimer(){
                    this.timer = setInterval(() => {
                        if(this.tempList.length > 0){

                            //记录执行耗时
                            this.timeConsumingAction(()=>{
                                //插入值
                                this.list.push(this.tempList[0]);
                                //请空值
                                this.tempList.shift();
                            });
                            //消息滚动到最底部
                            this.scrollMsg();
                        }
                    }, 200);
                },
                //模拟多个人同时说话
                demo(flag){
                    let arr = [];
                    for(let a = 0;a < this.person; a++){
                        arr.push({
                            user:a + 1,
                            text:`用户${a + 1}说了话`,
                        });
                    }
                    
                    if(flag != 'all'){
                        //加入队列
                        this.tempList = this.tempList.concat(arr);
                        //启动定时器
                        this.openTimer();
                    }else{
                        //记录执行耗时
                        this.timeConsumingAction(()=>{
                            //消息全部显示
                            this.list = this.list.concat(arr);
                        });
                        //消息滚动到最底部
                        this.scrollMsg();
                    }
                },
                //消息滚动到最底部
                scrollMsg(){
                    let dom = document.getElementById('message');
                    dom.scrollTop = dom.scrollHeight;
                },
                //记录执行耗时
                timeConsumingAction(fn){
                    var beginTime = +new Date();

                    fn();

                    var endTime = +new Date();
                    this.timeConsuming = endTime-beginTime;
                }
            }
        });
    </script>
</body>

</html>